package com.amumu.drama.common.modules.delivery.handler.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.amumu.drama.common.constant.DeliveryProviderEnum;
import com.amumu.drama.common.constant.DeliveryStatusEnum;
import com.amumu.drama.common.constant.FuluRespCode;
import com.amumu.drama.common.constant.OrderTypeEnum;
import com.amumu.drama.common.exception.Asserts;
import com.amumu.drama.common.modules.delivery.config.DeliveryConfig;
import com.amumu.drama.common.modules.delivery.dto.DeliveryStatusResp;
import com.amumu.drama.common.modules.delivery.dto.FuluDeliveryNotifyDTO;
import com.amumu.drama.common.modules.delivery.dto.req.DeliveryHandleDTO;
import com.amumu.drama.common.modules.delivery.handler.DeliveryHandler;
import com.amumu.drama.common.modules.fulu.dto.req.DirectOrderInfoQueryReq;
import com.amumu.drama.common.modules.fulu.dto.InputDirectOrderBusinessDto;
import com.amumu.drama.common.modules.fulu.dto.base.BaseResp;
import com.amumu.drama.common.modules.fulu.dto.resp.DirectOrderInfoQueryResp;
import com.amumu.drama.common.modules.fulu.dto.resp.DirectOrderResp;
import com.amumu.drama.common.modules.fulu.service.FuluService;
import com.amumu.drama.common.modules.order.dto.OmsOrderDetail;
import com.amumu.drama.common.utils.json.JsonObjectUtils;
import com.amumu.drama.mapper.PmsProductTemplateMapper;
import com.amumu.drama.model.OmsOrder;
import com.amumu.drama.model.OmsOrderItem;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author sunzhuang
 * @date 2024/6/27 09:03
 * @slogan 天下风云出我辈, 一入代码岁月催
 * @desc 福禄发货代码
 */
@Slf4j
@Service
public class FuluDeliveryHandler implements DeliveryHandler {

    @Autowired
    private PmsProductTemplateMapper productTemplateMapper;

    public static final String FAIL_MSG = "直充失败：";
    public static final String DELIVERY_MSG = "直充中：";

    /**
     * 发货渠道
     */
    @Override
    public List<String> type() {
        return Lists.newArrayList(DeliveryConfig.getDeliveryType(OrderTypeEnum.INTERFACE_DELIVERY, DeliveryProviderEnum.FULU),
                DeliveryConfig.getDeliveryType(OrderTypeEnum.MANUAL2INTERFACE_DELIVERY, DeliveryProviderEnum.FULU));
    }

    @Autowired
    private FuluService fuluService;

    /***
     * 处理发货（开始发货）
     * @param orderId
     */
    @Override
    public DeliveryStatusResp delivery(Long orderId, OmsOrderDetail orderDetail, DeliveryHandleDTO deliveryHandleDTO) {
        DeliveryStatusResp resp = new DeliveryStatusResp();
        resp.setDeliveryStatusEnum(DeliveryStatusEnum.WAIT_DELIVERY);
        resp.setApplyTime(LocalDateTime.now());
        List<OmsOrderItem> orderItemList = orderDetail.getOrderItemList();
        //;playerId:62;playerNickname:顾静;playerRegionId:35;
        JSONObject feature = JSONUtil.parseObj(orderDetail.getFeature());
        if (feature == null || feature.isEmpty()) {
            log.error("订单扩展信息异常，无法进行直充！orderDetail:{}", orderDetail);
            Asserts.fail("用户充值信息为空，无法进行直充！");
        }

        if (CollUtil.isEmpty(orderItemList) || orderItemList.size() != 1) {
            log.error("订单商品数量异常，无法进行直充！orderDetail:{}", orderDetail);
            Asserts.fail("订单商品数量不为1，无法进行直充！");
        }
        OmsOrderItem orderItem = orderItemList.get(0);
        //福禄直充
        InputDirectOrderBusinessDto directOrder = parseDirectOrderInput(orderDetail);
        directOrder.setProductId(orderItem.getProductSkuCode());
        directOrder.setCustomerOrderNo(orderDetail.getOrderSn());
        directOrder.setBuyNum(orderItem.getProductQuantity());
        directOrder.setExternalBizId(orderId + "");
        String reqInfo = JSONUtil.toJsonStr(directOrder);
        resp.setReqInfo(reqInfo);
        BaseResp<DirectOrderResp> directOrderResp = null;
        try {
            directOrderResp = fuluService.fuLuOrderDirect(directOrder);
        } catch (Exception e) {
            log.error("福禄直充接口调用失败：", e);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.FAIL);
            resp.setMsg(e.getMessage());
            resp.setApplyConfirmTime(LocalDateTime.now());
            return resp;
        }
        String respInfo = JSONUtil.toJsonStr(directOrderResp);
        resp.setRespInfo(respInfo);
        //记录福禄直充日志
        if (directOrderResp == null) {
            log.error("订单发起直充，但是接口没有响应，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
            resp.setMsg("福禄直充订单无响应");
            return resp;
        }
        DirectOrderResp result = directOrderResp.getResult();
        resp.setMsg(directOrderResp.getMessage());
        if (result != null) {
            resp.setDeliverySn(result.getOrderId());
            resp.setOrderSn(result.getCustomerOrderNo());
        }
        if (!FuluRespCode.SUCCESS.equals(directOrderResp.getCode())
                || result == null
                || FuluRespCode.ORDER_STATUS_FAIL.equals(result.getOrderState())) {
            log.error("订单直充失败，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.FAIL);
            resp.setMsg(FAIL_MSG + resp.getMsg());
            return resp;
        }
        if (FuluRespCode.ORDER_STATUS_SUCCESS.equals(result.getOrderState())) {
            log.info("福禄充值成功，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.SUCCESS);
            return resp;
        }
        log.info("福禄充值未开始，为充值中状态，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
        resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
        resp.setMsg(DELIVERY_MSG + resp.getMsg());
        resp.setApplyConfirmTime(LocalDateTime.now());
        return resp;
    }

    private InputDirectOrderBusinessDto parseDirectOrderInput(OmsOrderDetail orderDetail) {
        if (orderDetail == null || StrUtil.isBlank(orderDetail.getFeature())) {
            return new InputDirectOrderBusinessDto();
        }
        return JsonObjectUtils.parseJson(orderDetail.getFeature(), InputDirectOrderBusinessDto.class);
    }


    /**
     * 回调信息处理
     *
     * @param params
     * @param body
     */
    @Override
    public DeliveryStatusResp deliveryNotify(Map<String, String> params, String body) {
        DeliveryStatusResp resp = new DeliveryStatusResp();
        resp.setRespInfo(body);
        resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
        if (StrUtil.isBlank(body)) {
            log.error("福禄直充回调失败:回调请求body为空:{}", body);
            resp.setNotifyRespInfo(FuluRespCode.ORDER_STATUS_FAIL);
            return resp;
        }
        JSONObject jsonResult = JSONUtil.parseObj(body);
        FuluDeliveryNotifyDTO notifyDTO = jsonResult.toBean(FuluDeliveryNotifyDTO.class);
        if (notifyDTO == null) {
            log.error("福禄直充回调失败:回调请求body为空:{}", body);
            resp.setNotifyRespInfo(FuluRespCode.ORDER_STATUS_FAIL);
            return resp;
        }
        // todo 结果验签
        fillDeliveryStatusResp(resp, notifyDTO.getOrderId(), notifyDTO.getOrderStatus(), notifyDTO.getCustomerOrderNo(), notifyDTO.getRechargeDescription());
        resp.setApplyConfirmTime(LocalDateTimeUtil.parse(notifyDTO.getChargeFinishTime(), "yyyy-MM-dd HH:mm:ss"));
        resp.setNotifyRespInfo(FuluRespCode.ORDER_STATUS_SUCCESS);
        return resp;
    }

    /**
     * 填充发货状态响应
     *
     * @param resp
     */
    private void fillDeliveryStatusResp(DeliveryStatusResp resp, String orderId, String orderStatus, String customerOrderNo, String rechargeDescription) {
        resp.setMsg(rechargeDescription);
        switch (orderStatus) {
            case FuluRespCode.ORDER_STATUS_SUCCESS:
                resp.setDeliveryStatusEnum(DeliveryStatusEnum.SUCCESS);
                log.info("福禄充值成功，orderId:{}，customerOrderNo:{},rechargeDescription:{}", orderId, customerOrderNo, rechargeDescription);
                break;
            case FuluRespCode.ORDER_STATUS_FAIL:
                resp.setDeliveryStatusEnum(DeliveryStatusEnum.FAIL);
                resp.setMsg(FAIL_MSG + resp.getMsg());
                log.error("福禄直充失败，orderId:{}，customerOrderNo:{},rechargeDescription:{}", orderId, customerOrderNo, rechargeDescription);
                break;
            default:
                resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
                resp.setMsg(DELIVERY_MSG + resp.getMsg());
                log.error("福禄充值状态无效，orderId:{}，orderStatus:{},微玩订单号customerOrderNo:{},rechargeDescription:{}", orderId, orderStatus, customerOrderNo, rechargeDescription);
                break;
        }
        resp.setDeliverySn(orderId);
        resp.setOrderSn(customerOrderNo);
    }

    /***
     * 轮询查询更新发货状态
     * @param orderId
     * @param omsOrder
     */
    @Override
    public DeliveryStatusResp pollQueryDeliveryStatus(Long orderId, OmsOrder omsOrder) {
        DeliveryStatusResp resp = new DeliveryStatusResp();
        DirectOrderInfoQueryReq req = new DirectOrderInfoQueryReq();
        req.setCustomerOrderNo(omsOrder.getOrderSn());
        String reqInfo = JSONUtil.toJsonStr(req);
        resp.setReqInfo(reqInfo);
        resp.setApplyTime(LocalDateTime.now());
        BaseResp<DirectOrderInfoQueryResp> directOrderResp = fuluService.queryOrderInfo(req);
        String respInfo = JSONUtil.toJsonStr(directOrderResp);
        resp.setRespInfo(respInfo);
        //记录福禄直充日志
        if (directOrderResp == null) {
            log.error("福禄轮询查询订单失败，orderId:{},respInfo：{}", orderId, reqInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
            resp.setMsg("轮训查询福禄发货状态无响应");
            return resp;
        }
        DirectOrderInfoQueryResp result = directOrderResp.getResult();
        if (result != null) {
            resp.setDeliverySn(result.getOrderId());
            resp.setOrderSn(result.getCustomerOrderNo());
            resp.setApplyTime(LocalDateTimeUtil.parse(result.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
            resp.setApplyConfirmTime(LocalDateTimeUtil.parse(result.getFinishTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        resp.setMsg(directOrderResp.getMessage());
        if (!FuluRespCode.SUCCESS.equals(directOrderResp.getCode()) ||
                result == null ||
                FuluRespCode.ORDER_STATUS_FAIL.equals(result.getOrderState())) {
            log.error("轮询福禄直充失败，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.FAIL);
            resp.setMsg(FAIL_MSG + resp.getMsg());
        } else if (FuluRespCode.ORDER_STATUS_SUCCESS.equals(result.getOrderState())) {
            log.info("轮询福禄充值成功，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.SUCCESS);
        } else {
            log.info("轮询充值未开始，为充值中状态，orderId:{}，request:{},directOrderResp:{}", orderId, reqInfo, respInfo);
            resp.setDeliveryStatusEnum(DeliveryStatusEnum.DELIVERY);
            resp.setMsg(DELIVERY_MSG + resp.getMsg());
        }
        return resp;
    }
}
